import CrawlerPlus from '../common/utils/CrawlerPlus'
import fs from 'fs'
import cheerio from 'cheerio'
import config from '../config/Config'
type Id = number | string

interface List {
  text: string
  href: string
  author: string
  type: number
}

interface Details {
  chapterId: Id
  content: string
  next?: string
}

interface Chapter {
  name: string
  href: string
  content?: string
}

interface ChapterList {
  cover: string
  name: string
  bookId: number
  content: Chapter[]
  isLastPage?: boolean
}

interface String {
  replaceAll(input: string, output: string): any
}
class Fiction {
  /**
   * 根据type所有的book列表
   * @param href
   * @param page
   * @param type
   * @param title
   * @returns
   */
  public static async getAllListByType(href: string, page: number, type: number, title?: string) {
    // let num: number = 1

    const arr: number[] = []
    for (let i = 0; i < page - 1; i++) {
      arr.push(i)
    }
    const _list = await Promise.all(
      arr.map(async (num) => {
        const link = `${href}${num}.html`
        const res = await CrawlerPlus.getFictionData(link)
        if (!res) {
          return false
        }
        const $: cheerio.Root = cheerio.load(res)
        const nameCallback = (item: cheerio.Element) => {
          return $(item).find('.blue').text()
        }
        const hrefCallback = (item: cheerio.Element) => {
          return $(item).find('.blue').attr('href')!
        }
        const authorCallback = (item: cheerio.Element) => {
          return $(item).text().split('/')[1]
        }
        const typeCallback = (item: cheerio.Element) => {
          return type
        }
        console.log(num)
        return this.getListData($, '.cover .line', nameCallback, hrefCallback, authorCallback, typeCallback)
      })
    )
    const list: List[] = []
    _list.forEach((item) => {
      if (item) {
        list.push(...item)
      }
    })
    title ? (title = title) : (title = new Date().getTime().toString())
    // await fs.writeFileSync(`${process.cwd()}/src/public/json/${title}.json`,JSON.stringify(list))
    // title ? title = title : title = '1618891062426'
    // try {
    //     await fs.mkdirSync(`${process.cwd()}/src/public/json/${title}`)
    // } catch (error) {
    //    console.log(error)
    // }

    // const list:List[] = JSON.parse(await fs.readFileSync(`${process.cwd()}/src/public/json/${title}.json`).toString())
    const content = ''
    // for(let i =0;i<list.length;i++){
    //     //{ text: '天道恩仇', href: '/s/138531.html', chapterId: 858 },
    // //     const item = list[i]
    // //     console.log('list for',item.href,item.chapterId)
    // //     try {
    // //         const details = await this.getDetails(item.href,item.chapterId,item.text)
    // //         content = `${content}\n${details}`

    // //     } catch (error) {
    // //         console.log(error)
    // //     }
    // //     if(i === 10){
    // //         break
    // //     }
    // //     //await getDetails(item.href,item.chapterId,title)
    // }
    // await fs.writeFileSync(`${process.cwd()}/${config.base}/public/txt/${title}_txt.txt`,content)
    return list
  }
  public static async getListData(
    $: cheerio.Root,
    aClass: string,
    nameCallback: (data: cheerio.Element) => string,
    hrefCallback: (data: cheerio.Element) => string,
    authorCallback: (data: cheerio.Element) => string,
    typeCallback: (data: cheerio.Element) => number
  ) {
    return new Promise<List[]>((resolve, reject) => {
      const list: List[] = []
      $(aClass).each((index, item) => {
        list.push({
          text: nameCallback(item), //.split('章 ')[1],
          href: hrefCallback(item),
          author: authorCallback(item),
          type: typeCallback(item),
        })
      })
      resolve(list)
    }).catch((error) => {
      console.log(error)
    })
  }

  // 获取章节列表
  public static async getChapterList(href: string, bookId: number) {
    let num = 1
    const list: ChapterList[] = []
    for (let i = 1; i > -1; i++) {
      console.log(num)
      try {
        const hrefArr = href.split('.html')
        const link = `${hrefArr[0]}_${num}.html`
        // if(num === 1){
        //     link = `${href}`
        // }
        console.log(link)
        const res = await CrawlerPlus.getFictionData(link)
        if (!res) {
          break
        }
        const $: cheerio.Root = cheerio.load(res)
        const chapterList = await this.getChapterListData($, bookId)
        console.log(chapterList)
        if (!chapterList) {
          break
        }
        list.push(chapterList)
        if (chapterList.isLastPage) {
          break
        }
      } catch (error) {
        console.log(error)
        break
      }
      num++
    }
    const data: {
      cover: string
      content: Chapter[]
    } = {
      cover: list[0].cover,
      content: [],
    }

    list.forEach((item, index) => {
      data.content.push(...item.content)
    })
    return data
  }

  public static async getChapterListData($: cheerio.Root, bookId: number) {
    return new Promise<ChapterList>((resolve, reject) => {
      const content: Chapter[] = []
      $('.intro.str-over-dot')
        .next()
        .next()
        .next()
        .find('li')
        .each((index, item) => {
          content.push({
            name: $(item).text().trim().replace('\n', ''),
            href: $(item).find('a').attr('href')!,
          })
        })
      const chapterList: ChapterList = {
        cover: $('.block_img2 img').attr('src')!,
        name: $('.block_txt2 h2 a').text().trim().replace('\n', ''),
        content,
        bookId,
        isLastPage:
          $('.intro.str-over-dot').next().find('li').first().find('a').attr('href') ===
          content[content.length - 1].href,
      }
      resolve(chapterList)
    }).catch((error) => {
      console.log(error)
    })
  }

  public static async getDetails(href: string, chapterId: Id, title: string) {
    const list: Details[] = []
    const res = await this.getDetailsData(href, chapterId)
    if (!res) {
      return ''
    }
    list.push(res)
    let next = res.next
    while (next) {
      const s = await this.getDetailsData(next, chapterId)
      if (!s) {
        break
      }
      next = s.next
      list.push(s)
    }
    const details: Details = list[0]
    let content: string = details.content
    list.forEach((element) => {
      content = content + element.content
    })
    content = content.split('    ').join()
    details.content = content
    //await fs.writeFileSync(`${process.cwd()}/src/public/json/${title}/${chapterId}.json`,JSON.stringify(details))
    //console.log('list:' + JSON.stringify(details))
    return `## 第${chapterId}章 ${title} ${content}`
  }

  public static async getDetailsData(link: string, chapterId: Id) {
    return new Promise<Details>(async (resolve, reject) => {
      let details: Details
      const res = await CrawlerPlus.getFictionData(link)
      if (!res) {
        reject(null)
        return
      }
      const $: cheerio.Root = cheerio.load(res)
      const content = $('#TextContent').text()
      //const content = $('#TextContent').html() || ''
      let next = ''
      $('.fenyeA.button.sizebg.sizebgon.yeurl').each((index, item) => {
        if ($(item).text().indexOf('下一页') > -1) {
          next = $(item).attr('href') || ''
        }
      })
      details = {
        chapterId,
        content,
        next,
      }
      resolve(details)
    }).catch((error) => {
      console.log(error)
    })
  }
}

export default Fiction
